In this section, we will compare the performance of three different models: Linear, Exponential, and Log-Transformed for each fungal species at various temperatures. We will compare the following metrics:
df <- read.csv("Rosalynn Tidy data.csv")
#Filter week 1-5, Suillus data up to week 6.
df_1_5 <- df %>%
filter(Week %in% 1:5)
# Convert relevant columns to factors
df_1_5$Temperature..Celsius. <- as.factor(df_1_5$Temperature..Celsius.)
#df_1_5$Week <- as.factor(df_1_5$Week)
df_1_5$Species <- as.factor(df_1_5$Species)
# Rename the column
colnames(df_1_5)[colnames(df_1_5) == "Temperature..Celsius."] <- "Temperature"
# Initialize an empty list to store model metrics
model_metrics <- list()
# Loop over each species and temperature to fit models and calculate metrics
for(species in unique(df_1_5$Species)) {
for(temp in unique(df_1_5$Temperature)) {
# Filter the data for this species and temperature
df_subset <- df_1_5 %>% filter(Species == species, Temperature == temp)
# Fit the Linear Model
linear_model <- lm(Growth ~ Week, data = df_subset)
# Fit the Exponential Model (log-transformed linear)
exp_model <- lm(log(Growth) ~ Week, data = df_subset)
# Fit the Logarithmic Model (Growth ~ log(Week))
log_fit_model <- lm(Growth ~ log(Week), data = df_subset)
# Calculate Metrics for each model
metrics <- data.frame(
Species = species,
Temperature = temp,
Metric = c("RSS", "Adjusted R-squared", "AIC", "BIC"),
Linear_Model = c(sum(residuals(linear_model)^2),
summary(linear_model)$adj.r.squared,
AIC(linear_model),
BIC(linear_model)),
Exponential_Model = c(sum(residuals(exp_model)^2),
summary(exp_model)$adj.r.squared,
AIC(exp_model),
BIC(exp_model)),
Logarithmic_Model = c(sum(residuals(log_fit_model)^2),
summary(log_fit_model)$adj.r.squared,
AIC(log_fit_model),
BIC(log_fit_model))
)
# Determine the best model for each metric
metrics$Best_Model <- sapply(1:nrow(metrics), function(i) {
if (metrics$Metric[i] == "Adjusted R-squared") {
# For Adjusted R-squared, higher is better
if (metrics$Linear_Model[i] == max(metrics$Linear_Model[i], metrics$Exponential_Model[i], metrics$Logarithmic_Model[i])) {
"Linear Model"
} else if (metrics$Exponential_Model[i] == max(metrics$Linear_Model[i], metrics$Exponential_Model[i], metrics$Logarithmic_Model[i])) {
"Exponential Model"
} else {
"Logarithmic Model"
}
} else {
# For RSS, AIC, and BIC, lower is better
if (metrics$Linear_Model[i] == min(metrics$Linear_Model[i], metrics$Exponential_Model[i], metrics$Logarithmic_Model[i])) {
"Linear Model"
} else if (metrics$Exponential_Model[i] == min(metrics$Linear_Model[i], metrics$Exponential_Model[i], metrics$Logarithmic_Model[i])) {
"Exponential Model"
} else {
"Logarithmic Model"
}
}
})
# Store the metrics in the list
model_metrics[[paste(species, temp, sep = "_")]] <- metrics
}
}
# Combine all metrics into one data frame
model_comparison <- do.call(rbind, model_metrics)
# Display the table of model comparison with scrolling enabled for rows
model_comparison %>%
kbl(caption = "Model Comparison for Different Species and Temperatures") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE,
fixed_thead = TRUE) %>%
scroll_box(height = "400px")
| Species | Temperature | Metric | Linear_Model | Exponential_Model | Logarithmic_Model | Best_Model | |
|---|---|---|---|---|---|---|---|
| Suillus lakei_15.1 | Suillus lakei | 15 | RSS | 272.5171720 | 48.4593445 | 308.8850664 | Exponential Model |
| Suillus lakei_15.2 | Suillus lakei | 15 | Adjusted R-squared | 0.4613154 | 0.4191081 | 0.3894270 | Linear Model |
| Suillus lakei_15.3 | Suillus lakei | 15 | AIC | 378.5981283 | 212.8083901 | 390.6238204 | Exponential Model |
| Suillus lakei_15.4 | Suillus lakei | 15 | BIC | 386.2911729 | 220.5014347 | 398.3168650 | Exponential Model |
| Suillus lakei_20.1 | Suillus lakei | 20 | RSS | 1002.9973785 | 83.2938163 | 1119.0928300 | Exponential Model |
| Suillus lakei_20.2 | Suillus lakei | 20 | Adjusted R-squared | 0.4608752 | 0.4044651 | 0.3984724 | Linear Model |
| Suillus lakei_20.3 | Suillus lakei | 20 | AIC | 503.6905967 | 264.8067059 | 514.2050436 | Exponential Model |
| Suillus lakei_20.4 | Suillus lakei | 20 | BIC | 511.3836413 | 272.4997505 | 521.8980882 | Exponential Model |
| Suillus lakei_25.1 | Suillus lakei | 25 | RSS | 781.7938038 | 65.6273240 | 805.7073113 | Exponential Model |
| Suillus lakei_25.2 | Suillus lakei | 25 | Adjusted R-squared | 0.4289472 | 0.4447257 | 0.4114798 | Exponential Model |
| Suillus lakei_25.3 | Suillus lakei | 25 | AIC | 479.7715107 | 241.9220169 | 482.6639438 | Exponential Model |
| Suillus lakei_25.4 | Suillus lakei | 25 | BIC | 487.4645552 | 249.6150614 | 490.3569883 | Exponential Model |
| Rhizopogon Evadens_15.1 | Rhizopogon Evadens | 15 | RSS | 86.1196845 | 13.2576726 | 103.3863906 | Exponential Model |
| Rhizopogon Evadens_15.2 | Rhizopogon Evadens | 15 | Adjusted R-squared | 0.5835773 | 0.6896881 | 0.5000860 | Exponential Model |
| Rhizopogon Evadens_15.3 | Rhizopogon Evadens | 15 | AIC | 223.2203249 | 88.4966925 | 236.3772683 | Exponential Model |
| Rhizopogon Evadens_15.4 | Rhizopogon Evadens | 15 | BIC | 230.0503232 | 95.3266909 | 243.2072666 | Exponential Model |
| Rhizopogon Evadens_20.1 | Rhizopogon Evadens | 20 | RSS | 81.1488243 | 10.9114338 | 93.0074793 | Exponential Model |
| Rhizopogon Evadens_20.2 | Rhizopogon Evadens | 20 | Adjusted R-squared | 0.7593021 | 0.7736558 | 0.7241278 | Exponential Model |
| Rhizopogon Evadens_20.3 | Rhizopogon Evadens | 20 | AIC | 218.9396942 | 74.4735953 | 228.7601419 | Exponential Model |
| Rhizopogon Evadens_20.4 | Rhizopogon Evadens | 20 | BIC | 225.7696926 | 81.3035936 | 235.5901403 | Exponential Model |
| Rhizopogon Evadens_25.1 | Rhizopogon Evadens | 25 | RSS | 51.1903435 | 6.3616754 | 58.1441995 | Exponential Model |
| Rhizopogon Evadens_25.2 | Rhizopogon Evadens | 25 | Adjusted R-squared | 0.8685156 | 0.8745631 | 0.8506544 | Exponential Model |
| Rhizopogon Evadens_25.3 | Rhizopogon Evadens | 25 | AIC | 185.7668538 | 35.6281960 | 194.9378691 | Exponential Model |
| Rhizopogon Evadens_25.4 | Rhizopogon Evadens | 25 | BIC | 192.5968522 | 42.4581944 | 201.7678674 | Exponential Model |
| Rhizopogon idahoensis_15.1 | Rhizopogon idahoensis | 15 | RSS | 18.0173406 | 1.9029686 | 44.3805142 | Exponential Model |
| Rhizopogon idahoensis_15.2 | Rhizopogon idahoensis | 15 | Adjusted R-squared | 0.9365388 | 0.9605924 | 0.8436818 | Exponential Model |
| Rhizopogon idahoensis_15.3 | Rhizopogon idahoensis | 15 | AIC | 110.5832836 | -51.2669267 | 175.4888245 | Exponential Model |
| Rhizopogon idahoensis_15.4 | Rhizopogon idahoensis | 15 | BIC | 117.4132820 | -44.4369284 | 182.3188228 | Exponential Model |
| Rhizopogon idahoensis_20.1 | Rhizopogon idahoensis | 20 | RSS | 141.0385235 | 8.7132622 | 147.8315730 | Exponential Model |
| Rhizopogon idahoensis_20.2 | Rhizopogon idahoensis | 20 | Adjusted R-squared | 0.8269137 | 0.8564575 | 0.8185771 | Exponential Model |
| Rhizopogon idahoensis_20.3 | Rhizopogon idahoensis | 20 | AIC | 258.7375692 | 58.2761187 | 262.1244878 | Exponential Model |
| Rhizopogon idahoensis_20.4 | Rhizopogon idahoensis | 20 | BIC | 265.5675675 | 65.1061171 | 268.9544862 | Exponential Model |
| Rhizopogon idahoensis_25.1 | Rhizopogon idahoensis | 25 | RSS | 146.0640837 | 6.1040871 | 220.0835233 | Exponential Model |
| Rhizopogon idahoensis_25.2 | Rhizopogon idahoensis | 25 | Adjusted R-squared | 0.9028412 | 0.9082441 | 0.8536050 | Exponential Model |
| Rhizopogon idahoensis_25.3 | Rhizopogon idahoensis | 25 | AIC | 261.2584610 | 32.6522046 | 290.7757012 | Exponential Model |
| Rhizopogon idahoensis_25.4 | Rhizopogon idahoensis | 25 | BIC | 268.0884593 | 39.4822030 | 297.6056996 | Exponential Model |
| Cenococcum geophilum_15.1 | Cenococcum geophilum | 15 | RSS | 7.1878215 | 0.7879639 | 11.8191430 | Exponential Model |
| Cenococcum geophilum_15.2 | Cenococcum geophilum | 15 | Adjusted R-squared | 0.7445867 | 0.9157614 | 0.5800165 | Exponential Model |
| Cenococcum geophilum_15.3 | Cenococcum geophilum | 15 | AIC | 45.1730730 | -7.8835153 | 57.1090498 | Exponential Model |
| Cenococcum geophilum_15.4 | Cenococcum geophilum | 15 | BIC | 48.7072345 | -4.3493538 | 60.6432113 | Exponential Model |
| Cenococcum geophilum_20.1 | Cenococcum geophilum | 20 | RSS | 27.5942390 | 0.2729779 | 60.0069928 | Exponential Model |
| Cenococcum geophilum_20.2 | Cenococcum geophilum | 20 | Adjusted R-squared | 0.8584880 | 0.9863473 | 0.6922651 | Exponential Model |
| Cenococcum geophilum_20.3 | Cenococcum geophilum | 20 | AIC | 77.4583261 | -33.3249922 | 96.1028241 | Exponential Model |
| Cenococcum geophilum_20.4 | Cenococcum geophilum | 20 | BIC | 80.9924876 | -29.7908307 | 99.6369856 | Exponential Model |
| Cenococcum geophilum_25.1 | Cenococcum geophilum | 25 | RSS | 26.8718899 | 0.7088069 | 66.0314738 | Exponential Model |
| Cenococcum geophilum_25.2 | Cenococcum geophilum | 25 | Adjusted R-squared | 0.9126857 | 0.9711796 | 0.7854453 | Exponential Model |
| Cenococcum geophilum_25.3 | Cenococcum geophilum | 25 | AIC | 76.8216958 | -10.4243741 | 98.3989138 | Exponential Model |
| Cenococcum geophilum_25.4 | Cenococcum geophilum | 25 | BIC | 80.3558573 | -6.8902126 | 101.9330753 | Exponential Model |
| Laccaria bicolor_15.1 | Laccaria bicolor | 15 | RSS | 10.1641654 | 2.2452263 | 31.1866296 | Exponential Model |
| Laccaria bicolor_15.2 | Laccaria bicolor | 15 | Adjusted R-squared | 0.9828993 | 0.9055001 | 0.9475299 | Linear Model |
| Laccaria bicolor_15.3 | Laccaria bicolor | 15 | AIC | 53.4885979 | 17.2471093 | 80.3955048 | Exponential Model |
| Laccaria bicolor_15.4 | Laccaria bicolor | 15 | BIC | 57.0227594 | 20.7812708 | 83.9296663 | Exponential Model |
| Laccaria bicolor_20.1 | Laccaria bicolor | 20 | RSS | 32.5923101 | 2.3459816 | 20.3178084 | Exponential Model |
| Laccaria bicolor_20.2 | Laccaria bicolor | 20 | Adjusted R-squared | 0.9604422 | 0.8754175 | 0.9753399 | Logarithmic Model |
| Laccaria bicolor_20.3 | Laccaria bicolor | 20 | AIC | 81.4535907 | 18.3006513 | 70.1117040 | Exponential Model |
| Laccaria bicolor_20.4 | Laccaria bicolor | 20 | BIC | 84.9877521 | 21.8348128 | 73.6458655 | Exponential Model |
| Laccaria bicolor_25.1 | Laccaria bicolor | 25 | RSS | 12.7693784 | 1.0852276 | 43.0128546 | Exponential Model |
| Laccaria bicolor_25.2 | Laccaria bicolor | 25 | Adjusted R-squared | 0.9772213 | 0.9364364 | 0.9232715 | Linear Model |
| Laccaria bicolor_25.3 | Laccaria bicolor | 25 | AIC | 58.9649575 | -0.2012898 | 88.1117340 | Exponential Model |
| Laccaria bicolor_25.4 | Laccaria bicolor | 25 | BIC | 62.4991190 | 3.3328717 | 91.6458955 | Exponential Model |
In this section, we build exponential models to describe the growth of fungi at different temperatures. We will visualize both the raw data and the predicted data from the exponential models, and offer the option to compare them in the same plot.
# Create a list to store the fitted models and predicted data
exponential_models <- list()
predicted_data_list <- list()
# Loop over each species and temperature to fit exponential models
for(species in unique(df_1_5$Species)) {
for(temp in unique(df_1_5$Temperature)) {
# Filter the data for this species and temperature
df_subset <- df_1_5 %>% filter(Species == species, Temperature == temp)
# Fit the Exponential Model (log-transformed linear)
exp_model <- lm(log(Growth) ~ Week, data = df_subset)
# Store the model
model_name <- paste("Exp_Model", species, temp, sep = "_")
exponential_models[[model_name]] <- exp_model
# Generate predicted values
predicted_log_growth <- predict(exp_model, newdata = df_subset)
predicted_growth <- exp(predicted_log_growth) # Back-transform to the original scale
# Store predicted data in a data frame
df_predicted <- df_subset %>%
mutate(Predicted_Growth = predicted_growth)
# Store the predicted data for later use
predicted_data_list[[model_name]] <- df_predicted
}
}
# Combine all predicted data into one data frame for easier use
all_predicted_data <- bind_rows(predicted_data_list)
# Print a sample of the predicted data
head(all_predicted_data)
## Temperature Species strain_ID Week Plate Growth Predicted_Growth
## 1 15 Suillus lakei Suilla 1 1 0.499 0.721077
## 2 15 Suillus lakei Suilla 1 2 0.712 0.721077
## 3 15 Suillus lakei Suilla 1 3 0.724 0.721077
## 4 15 Suillus lakei Suilla 1 4 0.673 0.721077
## 5 15 Suillus lakei Suilla 1 5 0.717 0.721077
## 6 15 Suillus lakei Suilla 1 6 0.577 0.721077
The table below summarizes the results of fitting exponential models for each fungal species at different temperatures. For each combination of species and temperature, the following details are provided:
# Initialize a data frame to store the summary information
model_summary <- data.frame(Species = character(),
Temperature = numeric(),
F_Value = numeric(),
P_Value = numeric(),
Degrees_of_Freedom = character(),
Equation = character(),
stringsAsFactors = FALSE)
# Loop over each species and temperature to fit exponential models and extract metrics
for(species in unique(df_1_5$Species)) {
for(temp in unique(df_1_5$Temperature)) {
# Filter the data for this species and temperature
df_subset <- df_1_5 %>% filter(Species == species, Temperature == temp)
# Fit the exponential model (log-transformed linear)
exp_model <- lm(log(Growth) ~ Week, data = df_subset)
# Extract model summary details
model_summary_info <- summary(exp_model)
# Extract F-value, P-value, and degrees of freedom
f_value <- model_summary_info$fstatistic[1]
p_value <- pf(f_value, model_summary_info$fstatistic[2], model_summary_info$fstatistic[3], lower.tail = FALSE)
df1 <- model_summary_info$fstatistic[2] # Numerator degrees of freedom
df2 <- model_summary_info$fstatistic[3] # Denominator degrees of freedom
# Extract the model equation
intercept <- coef(exp_model)[1]
slope <- coef(exp_model)[2]
equation <- paste0("log(Growth) = ", round(intercept, 4), " + ", round(slope, 4), " * Week")
# Store the results in the data frame
model_summary <- rbind(model_summary, data.frame(Species = species,
Temperature = temp,
F_Value = f_value,
P_Value = p_value,
Degrees_of_Freedom = paste(df1, df2, sep = ", "),
Equation = equation))
}
}
# Create a scrollable table
model_summary %>%
kbl(caption = "Exponential Model Summary for Each Species at Each Temperature") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = TRUE, fixed_thead = TRUE) %>%
scroll_box(height = "400px")
| Species | Temperature | F_Value | P_Value | Degrees_of_Freedom | Equation | |
|---|---|---|---|---|---|---|
| value | <i>S. lakei</i> | 15 | 69.54162 | 0 | 1, 94 | log(Growth) = -0.7402 + 0.4132 * Week |
| value1 | <i>S. lakei</i> | 20 | 65.52046 | 0 | 1, 94 | log(Growth) = -0.7776 + 0.5258 * Week |
| value2 | <i>S. lakei</i> | 25 | 77.08663 | 0 | 1, 94 | log(Growth) = -0.6257 + 0.5062 * Week |
| value3 | <i>R. evadens</i> | 15 | 158.80206 | 0 | 1, 70 | log(Growth) = -0.8093 + 0.437 * Week |
| value4 | <i>R. evadens</i> | 20 | 243.68149 | 0 | 1, 70 | log(Growth) = -0.5387 + 0.4911 * Week |
| value5 | <i>R. evadens</i> | 25 | 496.02153 | 0 | 1, 70 | log(Growth) = -0.5558 + 0.535 * Week |
| value6 | <i>R. idahoensis</i> | 15 | 1731.68367 | 0 | 1, 70 | log(Growth) = -0.813 + 0.5467 * Week |
| value7 | <i>R. idahoensis</i> | 20 | 424.62689 | 0 | 1, 70 | log(Growth) = -0.424 + 0.5793 * Week |
| value8 | <i>R. idahoensis</i> | 25 | 703.79203 | 0 | 1, 70 | log(Growth) = -0.3219 + 0.6242 * Week |
| value9 | <i>C. geophilum</i> | 15 | 251.03408 | 0 | 1, 22 | log(Growth) = -0.9864 + 0.4138 * Week |
| value10 | <i>C. geophilum</i> | 20 | 1662.65378 | 0 | 1, 22 | log(Growth) = -1.0123 + 0.6269 * Week |
| value11 | <i>C. geophilum</i> | 25 | 776.04545 | 0 | 1, 22 | log(Growth) = -0.9609 + 0.6901 * Week |
| value12 | <i>L. bicolor</i> | 15 | 221.38663 | 0 | 1, 22 | log(Growth) = -0.2943 + 0.656 * Week |
| value13 | <i>L. bicolor</i> | 20 | 162.61667 | 0 | 1, 22 | log(Growth) = 0.2903 + 0.5747 * Week |
| value14 | <i>L. bicolor</i> | 25 | 339.84252 | 0 | 1, 22 | log(Growth) = 0.0793 + 0.5651 * Week |
The plot below displays the perfect exponential growth curves for each fungal species at different temperatures. These curves are based on the exponential model fitted to the data, using the equation:
\[ \text{Growth} = e^{(\text{intercept} + \text{slope} \times \text{Week})} \]
For each fungal species at each temperature, an exponential growth model was fitted to the data. The general form of the model is:
\[ \text{Growth} = e^{(\text{intercept} + \text{slope} \times \text{Week})} \]
This model describes how the growth of the fungi changes over time. To determine how fast the growth changes with respect to time (week), we need to compute the derivative of the growth function with respect to the week.
To compute the derivative of the growth function, we apply the chain rule. The chain rule tells us how to differentiate composite functions like this one, where we have an exponent that depends on another variable (week).
We begin by differentiating the exponential function:
\[ \frac{d}{d\text{Week}} \left( e^{(\text{intercept} + \text{slope} \times \text{Week})} \right) \]
The chain rule gives us two parts: 1. The derivative of the exponential function, which is the same exponential function: \[ e^{(\text{intercept} + \text{slope} \times \text{Week})} \] 2. The derivative of the exponent \((\text{intercept} + \text{slope} \times \text{Week})\) with respect to week. The derivative of this linear term is just the slope: \[ \frac{d}{d\text{Week}} (\text{intercept} + \text{slope} \times \text{Week}) = \text{slope} \]
Multiplying the results of these two derivatives (following the chain rule), we get:
\[ \frac{d(\text{Growth})}{d(\text{Week})} = \text{slope} \times e^{(\text{intercept} + \text{slope} \times \text{Week})} \]
We know from the original model that:
\[ \text{Growth} = e^{(\text{intercept} + \text{slope} \times \text{Week})} \]
So, we can substitute this back into the derivative equation. Replacing the exponential term with Growth, we arrive at the simplified form:
\[ \frac{d(\text{Growth})}{d(\text{Week})} = \text{Growth} \times \text{slope} \]
In the table below, for each species and temperature combination, the derivative is expressed in the simplified form:
\[ \frac{d(\text{Growth})}{d(\text{Week})} = \text{Growth} \times \text{slope} \]
This equation provides a clear understanding of how the rate of growth evolves over time for each species at each temperature.
# Initialize a data frame to store the simplified derivative functions
derivative_summary <- data.frame(Species = character(),
Temperature = numeric(),
Derivative_Function = character(),
stringsAsFactors = FALSE)
# Loop over each species and temperature to compute simplified derivative functions
for(species in unique(df_1_5$Species)) {
for(temp in unique(df_1_5$Temperature)) {
# Filter the data for this species and temperature
df_subset <- df_1_5 %>% filter(Species == species, Temperature == temp)
# Fit the exponential model (log-transformed linear)
exp_model <- lm(log(Growth) ~ Week, data = df_subset)
# Extract the slope of the model
slope <- coef(exp_model)[2]
# The simplified derivative function is Growth * slope
derivative_function <- paste0("d(Growth)/d(Week) = Growth * ", round(slope, 4))
# Store the derivative function for this species and temperature
derivative_summary <- rbind(derivative_summary,
data.frame(Species = species,
Temperature = temp,
Derivative_Function = derivative_function))
}
}
# Display the final table
library(knitr)
library(kableExtra)
# Create a scrollable table
derivative_summary %>%
kbl(caption = "Simplified Derivative Functions of Exponential Models for Each Species at Each Temperature") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = TRUE, fixed_thead = TRUE) %>%
scroll_box(height = "400px")
| Species | Temperature | Derivative_Function |
|---|---|---|
| <i>S. lakei</i> | 15 | d(Growth)/d(Week) = Growth * 0.4132 |
| <i>S. lakei</i> | 20 | d(Growth)/d(Week) = Growth * 0.5258 |
| <i>S. lakei</i> | 25 | d(Growth)/d(Week) = Growth * 0.5062 |
| <i>R. evadens</i> | 15 | d(Growth)/d(Week) = Growth * 0.437 |
| <i>R. evadens</i> | 20 | d(Growth)/d(Week) = Growth * 0.4911 |
| <i>R. evadens</i> | 25 | d(Growth)/d(Week) = Growth * 0.535 |
| <i>R. idahoensis</i> | 15 | d(Growth)/d(Week) = Growth * 0.5467 |
| <i>R. idahoensis</i> | 20 | d(Growth)/d(Week) = Growth * 0.5793 |
| <i>R. idahoensis</i> | 25 | d(Growth)/d(Week) = Growth * 0.6242 |
| <i>C. geophilum</i> | 15 | d(Growth)/d(Week) = Growth * 0.4138 |
| <i>C. geophilum</i> | 20 | d(Growth)/d(Week) = Growth * 0.6269 |
| <i>C. geophilum</i> | 25 | d(Growth)/d(Week) = Growth * 0.6901 |
| <i>L. bicolor</i> | 15 | d(Growth)/d(Week) = Growth * 0.656 |
| <i>L. bicolor</i> | 20 | d(Growth)/d(Week) = Growth * 0.5747 |
| <i>L. bicolor</i> | 25 | d(Growth)/d(Week) = Growth * 0.5651 |
The raw growth rate was calculated for each fungal strain on each plate, at every temperature and time point (week). This method provides the growth rate for each individual replicate, without aggregating across plates. The growth rate measures how much the fungal colony’s area increased between consecutive time points.
The growth rate was computed using the following formula:
\[ \text{Growth Rate} = \frac{\text{Growth at Week}_n - \text{Growth at Week}_{n-1}}{\text{Week}_n - \text{Week}_{n-1}} \]
###Aggregated Raw Growth Rate for Each Species at Different Temperatures
This figure displays the aggregated raw growth rates for multiple fungal species grown at various temperatures (15°C, 20°C, and 25°C). The growth rate is calculated based on the change in the mean growth between consecutive weeks, aggregated across multiple replicate plates for each species at each temperature.
This niche curve represents the growth rate at week 5 (The highest growth rate) for various fungal species grown at different temperatures (15°C, 20°C, and 25°C). The growth rate was calculated using the derivative of an exponential growth model fitted to each species’ growth data.
# Step 1: Fit an exponential model for each species and temperature, and calculate the growth rate at Week 5
df_growth_rate_week5 <- data.frame(Species = character(),
Temperature = numeric(),
Growth_Rate_Week5 = numeric(),
stringsAsFactors = FALSE)
for(species in unique(df_1_5$Species)) {
for(temp in unique(df_1_5$Temperature)) {
# Filter the data for this species and temperature
df_subset <- df_1_5 %>% filter(Species == species, Temperature == temp)
# Fit the exponential model (log-transformed linear)
exp_model <- lm(log(Growth) ~ Week, data = df_subset)
# Extract coefficients for the model (intercept and slope)
intercept <- coef(exp_model)[1]
slope <- coef(exp_model)[2]
# Calculate the growth at Week 5
growth_at_week5 <- exp(intercept + slope * 5) # Growth at week 5
# Calculate the derivative (growth rate) at Week 5
growth_rate_at_week5 <- growth_at_week5 * slope
# Store the results in the dataframe
df_growth_rate_week5 <- rbind(df_growth_rate_week5,
data.frame(Species = species,
Temperature = as.numeric(temp), # Ensure Temperature is numeric
Growth_Rate_Week5 = growth_rate_at_week5))
}
}
# Step 2: Create the plot of maximum growth rate at week 5 for each temperature
plot_growth_rate_temp <- ggplot(df_growth_rate_week5, aes(x = Temperature, y = Growth_Rate_Week5, color = Species)) +
geom_point(size = 4) + # Plot points for growth rate at week 5
geom_line(aes(group = Species), size = 1.2) + # Connect points by species
scale_x_continuous(breaks = c(15, 20, 25), labels = c("15°C", "20°C", "25°C")) + # Label temperature in °C
labs(title = "Niche Curve of Different Fungi",
x = "Temperature (°C)", y = "Growth Rate at Week 5 (cm^2 per Week)") +
theme_minimal() +
theme(
strip.text.x = element_text(size = 10), # Adjust species label size
axis.text = element_text(size = 10), # Adjust axis text size
axis.title = element_text(size = 12), # Adjust axis title size
plot.title = element_text(size = 14, face = "bold"), # Adjust title size
legend.position = "right" # Keep the legend for species
)
# Step 3: Convert to interactive plot using plotly
interactive_plot_growth_rate_temp <- ggplotly(plot_growth_rate_temp)
# Step 4: Display the interactive plot
interactive_plot_growth_rate_temp
# Step 1: Aggregate the data by calculating the mean growth for each species, temperature, and week across plates
df_aggregated <- df_1_5 %>%
group_by(Species, Temperature, Week) %>%
summarize(
Mean_Growth = mean(Growth, na.rm = TRUE) # Calculate mean growth across plates
) %>%
arrange(Species, Temperature, Week)
# Step 2: Calculate the growth rate using the aggregated data
df_aggregated_growth_rate <- df_aggregated %>%
mutate(
Previous_Week = lag(Week), # Previous week for each species and temperature
Previous_Mean_Growth = lag(Mean_Growth), # Previous mean growth value
Growth_Rate = ifelse(is.na(Previous_Week) | is.na(Previous_Mean_Growth), 0,
(Mean_Growth - Previous_Mean_Growth) / (Week - Previous_Week)) # Calculate mean growth rate
) %>%
ungroup()
# Step 3: Find the maximum growth rate for each species and temperature
df_max_growth_rate <- df_aggregated_growth_rate %>%
group_by(Species, Temperature) %>%
summarize(Max_Growth_Rate = max(Growth_Rate, na.rm = TRUE)) %>%
mutate(Temperature = as.numeric(Temperature)) %>% # Convert Temperature to numeric
ungroup()
# Step 4: Create the plot of maximum growth rate for each temperature
plot_max_growth_rate_temp <- ggplot(df_max_growth_rate, aes(x = Temperature, y = Max_Growth_Rate, color = Species)) +
geom_point(size = 4) + # Plot points for max growth rate
geom_line(aes(group = Species), size = 1.2) + # Connect points by species
scale_x_continuous(breaks = c(15, 20, 25), labels = c("15°C", "20°C", "25°C")) + # Label temperature in °C
labs(title = "Raw Niche Curve",
x = "Temperature (°C)", y = "Maximum Growth Rate (cm^2 per Week)") +
theme_minimal() +
theme(
axis.text = element_text(size = 10), # Adjust axis text size
axis.title = element_text(size = 12), # Adjust axis title size
plot.title = element_text(size = 14, face = "bold"), # Adjust title size
legend.position = "right" # Keep the legend for species
)
# Step 5: Convert to interactive plot using plotly
interactive_plot_max_growth_rate_temp <- ggplotly(plot_max_growth_rate_temp)
# Step 6: Display the interactive plot
interactive_plot_max_growth_rate_temp